﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace System
{
	public static class Algebra
	{
		public static int[] DHondt(int NumTile, params int[] weights)
		{
			int L = weights.Length;
			int[] Nums = new int[L];
			for (int i = 0; i < L; i++)
				Nums[i] = 0;
			for (int i = 0; i < NumTile; i++)
			{
				double[] check = new double[L];
				for (int j = 0; j < L; j++)
					check[j] = weights[j] / (1.0 + Nums[j]);
				int R = 0;
				for (int j = 1; j < L; j++)
					if (check[j] > check[R])
						R = j;
				Nums[R]++;
			}
			return Nums;
		}

		public static void Swap(ref int value1, ref int value2)
		{
			value1 += value2;
			value2 = value1 - value2;
			value1 -= value2;
		}
		public static void Swap(ref double value1, ref double value2)
		{
			value1 += value2;
			value2 = value1 - value2;
			value1 -= value2;
		}
	}
	public class TimeSeries
	{
		public List<KeyValuePair<DateTime, double>> Values = new List<KeyValuePair<DateTime, double>>();
		public void Add(DateTime T, double V)
		{
			Values.Add(new KeyValuePair<DateTime, double>(T, V));
			Sort();
		}
		public void Add(int y, int m, int d, double V)
		{
			Values.Add(new KeyValuePair<DateTime, double>(new DateTime(y, m, d), V));
			Sort();
		}
		public KeyValuePair<DateTime, double> First, Last;
		public double StartAmount
		{
			get
			{
				return First.Value;
			}
		}
		public double CurrentAmount
		{
			get
			{
				return Last.Value;
			}
		}

		public void Sort()
		{
			Values.Sort((x1, x2) => x1.Key.CompareTo(x2.Key));
			First = Values[0];
			Last = Values[Values.Count - 1];
		}
		public TimeSpan Duration
		{
			get
			{
				return Last.Key - First.Key;
			}
		}
		public double Change
		{
			get
			{
				return Last.Value - First.Value;
			}
		}
		public double Rate
		{
			get
			{
				return Last.Value / First.Value;
			}
		}

		public double ProjectLog(DateTime TargetTime)
		{
			if (Change > 0)
			{
				return CurrentAmount;
			}
			else
			{
				Console.WriteLine("Negative change");
				return 0;
			}
		}
		public double PercentLog(double target)
		{
			if (Change > 0)
				return 1 / Math.Log(target / StartAmount, Rate);
			else
				return 0;
		}
		public DateTime PredictTime(double target)
		{
			if (Change > 0)
			{
				double Q = 1 / PercentLog(target);
				return First.Key + new TimeSpan((long)(Duration.TotalSeconds * Q * 1e7));
			}
			else
			{
				Console.WriteLine("Negative change");
				return DateTime.MinValue;
			}
		}

		#region IO
		public static void WriteRow(String FN, DateTime time, string name, double amount, string ext = "")
		{
			if (!File.Exists(FN))
				File.Create(FN).Close();
			File.AppendAllText(FN, time.ToString("yyyy-MM-dd HH:mm") + "\t" + name + "\t" + amount.ToString("0.00") + (ext != "" ? "\t" + ext : "") + "\n");
		}
		#endregion
	}
}